home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / g / gnu_c / crssrc16.zoo / src / cr_put.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-27  |  8.7 KB  |  406 lines

  1. /*
  2.  * Copyright (c) 1981 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)cr_put.c    5.3 (Berkeley) 6/30/88";
  20. #endif /* not lint */
  21.  
  22. # include    "curses.ext"
  23. #include <string.h>
  24. #include <termcap.h>
  25.  
  26. # define    HARDTABS    8
  27.  
  28. static int        plod __PROTO((int));
  29. static int        plodput __PROTO((int));
  30.  
  31. /*
  32.  * Terminal driving and line formatting routines.
  33.  * Basic motion optimizations are done here as well
  34.  * as formatting of lines (printing of control characters,
  35.  * line numbering and the like).
  36.  */
  37.  
  38. /*
  39.  * Sync the position of the output cursor.
  40.  * Most work here is rounding for terminal boundaries getting the
  41.  * column position implied by wraparound or the lack thereof and
  42.  * rolling up the screen to get destline on the screen.
  43.  */
  44.  
  45. static int    outcol, outline, destcol, destline;
  46.  
  47. WINDOW        *_win;
  48.  
  49. void mvcur(ly, lx, y, x)
  50. int    ly, lx, y, x; {
  51.  
  52. #ifdef DEBUG
  53.     fprintf(outf, "MVCUR: moving cursor from (%d,%d) to (%d,%d)\n", ly, lx, y, x);
  54. #endif
  55.     destcol = x;
  56.     destline = y;
  57.     outcol = lx;
  58.     outline = ly;
  59.     fgoto();
  60. }
  61.  
  62. void fgoto()
  63. {
  64.     reg char    *cgp;
  65.     reg int        l, c;
  66.  
  67.     if (destcol >= COLS) {
  68.         destline += destcol / COLS;
  69.         destcol %= COLS;
  70.     }
  71.     if (outcol >= COLS) {
  72.         l = (outcol + 1) / COLS;
  73.         outline += l;
  74.         outcol %= COLS;
  75.         if (AM == 0) {
  76.             while (l > 0) {
  77.                 if (_pfast)
  78.                     if (CR)
  79.                         _puts(CR);
  80.                     else
  81.                         _putchar('\r', stdout);
  82.                 if (NL)
  83.                     _puts(NL);
  84.                 else
  85.                     _putchar('\n', stdout);
  86.                 l--;
  87.             }
  88.             outcol = 0;
  89.         }
  90.         if (outline > LINES - 1) {
  91.             destline -= outline - (LINES - 1);
  92.             outline = LINES - 1;
  93.         }
  94.     }
  95.     if (destline >= LINES) {
  96.         l = destline;
  97.         destline = LINES - 1;
  98.         if (outline < LINES - 1) {
  99.             c = destcol;
  100.             if (_pfast == 0 && !CA)
  101.                 destcol = 0;
  102.             fgoto();
  103.             destcol = c;
  104.         }
  105.         while (l >= LINES) {
  106.             /*
  107.              * The following linefeed (or simulation thereof)
  108.              * is supposed to scroll up the screen, since we
  109.              * are on the bottom line.  We make the assumption
  110.              * that linefeed will scroll.  If ns is in the
  111.              * capability list this won't work.  We should
  112.              * probably have an sc capability but sf will
  113.              * generally take the place if it works.
  114.              *
  115.              * Superbee glitch:  in the middle of the screen we
  116.              * have to use esc B (down) because linefeed screws up
  117.              * in "Efficient Paging" (what a joke) mode (which is
  118.              * essential in some SB's because CRLF mode puts garbage
  119.              * in at end of memory), but you must use linefeed to
  120.              * scroll since down arrow won't go past memory end.
  121.              * I turned this off after recieving Paul Eggert's
  122.              * Superbee description which wins better.
  123.              */
  124.             if (NL /* && !XB */ && _pfast)
  125.                 _puts(NL);
  126.             else
  127.                 _putchar('\n', stdout);
  128.             l--;
  129.             if (_pfast == 0)
  130.                 outcol = 0;
  131.         }
  132.     }
  133.     if (destline < outline && !(CA || UP))
  134.         destline = outline;
  135.     if (CA) {
  136.         cgp = tgoto(CM, destcol, destline);
  137.         if (plod((int)strlen(cgp)) > 0)
  138.             plod(0);
  139.         else
  140.             tputs(cgp, 0, _fputchar);
  141.     }
  142.     else
  143.         plod(0);
  144.     outline = destline;
  145.     outcol = destcol;
  146. }
  147.  
  148. /*
  149.  * Move (slowly) to destination.
  150.  * Hard thing here is using home cursor on really deficient terminals.
  151.  * Otherwise just use cursor motions, hacking use of tabs and overtabbing
  152.  * and backspace.
  153.  */
  154.  
  155. static int plodcnt, plodflg;
  156.  
  157. static int plodput(c)
  158. int c;
  159. {
  160.     if (plodflg)
  161.         plodcnt--;
  162.     else
  163.         _putchar(c, stdout);
  164. }
  165.  
  166. static int plod(cnt)
  167. int cnt;
  168. {
  169.     register int i, j, k;
  170.     register int soutcol, soutline;
  171.  
  172.     plodcnt = plodflg = cnt;
  173.     soutcol = outcol;
  174.     soutline = outline;
  175.     /*
  176.      * Consider homing and moving down/right from there, vs moving
  177.      * directly with local motions to the right spot.
  178.      */
  179.     if (HO) {
  180.         /*
  181.          * i is the cost to home and tab/space to the right to
  182.          * get to the proper column.  This assumes ND space costs
  183.          * 1 char.  So i+destcol is cost of motion with home.
  184.          */
  185.         if (GT)
  186.             i = (destcol / HARDTABS) + (destcol % HARDTABS);
  187.         else
  188.             i = destcol;
  189.         /*
  190.          * j is cost to move locally without homing
  191.          */
  192.         if (destcol >= outcol) {    /* if motion is to the right */
  193.             j = destcol / HARDTABS - outcol / HARDTABS;
  194.             if (GT && j)
  195.                 j += destcol % HARDTABS;
  196.             else
  197.                 j = destcol - outcol;
  198.         }
  199.         else
  200.             /* leftward motion only works if we can backspace. */
  201.             if (outcol - destcol <= i && (BS || BC))
  202.                 i = j = outcol - destcol; /* cheaper to backspace */
  203.             else
  204.                 j = i + 1; /* impossibly expensive */
  205.  
  206.         /* k is the absolute value of vertical distance */
  207.         k = outline - destline;
  208.         if (k < 0)
  209.             k = -k;
  210.         j += k;
  211.  
  212.         /*
  213.          * Decision.  We may not have a choice if no UP.
  214.          */
  215.         if (i + destline < j || (!UP && destline < outline)) {
  216.             /*
  217.              * Cheaper to home.  Do it now and pretend it's a
  218.              * regular local motion.
  219.              */
  220.             tputs(HO, 0, plodput);
  221.             outcol = outline = 0;
  222.         }
  223.         else if (LL) {
  224.             /*
  225.              * Quickly consider homing down and moving from there.
  226.              * Assume cost of LL is 2.
  227.              */
  228.             k = (LINES - 1) - destline;
  229.             if (i + k + 2 < j && (k<=0 || UP)) {
  230.                 tputs(LL, 0, plodput);
  231.                 outcol = 0;
  232.                 outline = LINES - 1;
  233.             }
  234.         }
  235.     }
  236.     else
  237.     /*
  238.      * No home and no up means it's impossible.
  239.      */
  240.         if (!UP && destline < outline)
  241.             return -1;
  242.     if (GT)
  243.         i = destcol % HARDTABS + destcol / HARDTABS;
  244.     else
  245.         i = destcol;
  246. /*
  247.     if (BT && outcol > destcol && (j = (((outcol+7) & ~7) - destcol - 1) >> 3)) {
  248.         j *= (k = (int)strlen(BT));
  249.         if ((k += (destcol&7)) > 4)
  250.             j += 8 - (destcol&7);
  251.         else
  252.             j += k;
  253.     }
  254.     else
  255. */
  256.         j = outcol - destcol;
  257.     /*
  258.      * If we will later need a \n which will turn into a \r\n by
  259.      * the system or the terminal, then don't bother to try to \r.
  260.      */
  261.     if ((NONL || !_pfast) && outline < destline)
  262.         goto dontcr;
  263.     /*
  264.      * If the terminal will do a \r\n and there isn't room for it,
  265.      * then we can't afford a \r.
  266.      */
  267.     if (NC && outline >= destline)
  268.         goto dontcr;
  269.     /*
  270.      * If it will be cheaper, or if we can't back up, then send
  271.      * a return preliminarily.
  272.      */
  273.     if (j > i + 1 || outcol > destcol && !BS && !BC) {
  274.         /*
  275.          * BUG: this doesn't take the (possibly long) length
  276.          * of CR into account.
  277.          */
  278.         if (CR)
  279.             tputs(CR, 0, plodput);
  280.         else
  281.             plodput('\r');
  282.         if (NC) {
  283.             if (NL)
  284.                 tputs(NL, 0, plodput);
  285.             else
  286.                 plodput('\n');
  287.             outline++;
  288.         }
  289.         outcol = 0;
  290.     }
  291. dontcr:
  292.     while (outline < destline) {
  293.         outline++;
  294.         if (NL)
  295.             tputs(NL, 0, plodput);
  296.         else
  297.             plodput('\n');
  298.         if (plodcnt < 0)
  299.             goto out;
  300.         if (NONL || _pfast == 0)
  301.             outcol = 0;
  302.     }
  303.     if (BT)
  304.         k = (int)strlen(BT);
  305.     while (outcol > destcol) {
  306.         if (plodcnt < 0)
  307.             goto out;
  308. /*
  309.         if (BT && outcol - destcol > k + 4) {
  310.             tputs(BT, 0, plodput);
  311.             outcol--;
  312.             outcol &= ~7;
  313.             continue;
  314.         }
  315. */
  316.         outcol--;
  317.         if (BC)
  318.             tputs(BC, 0, plodput);
  319.         else
  320.             plodput('\b');
  321.     }
  322.     while (outline > destline) {
  323.         outline--;
  324.         tputs(UP, 0, plodput);
  325.         if (plodcnt < 0)
  326.             goto out;
  327.     }
  328.     if (GT && destcol - outcol > 1) {
  329.         for (;;) {
  330.             i = tabcol(outcol, HARDTABS);
  331.             if (i > destcol)
  332.                 break;
  333.             if (TA)
  334.                 tputs(TA, 0, plodput);
  335.             else
  336.                 plodput('\t');
  337.             outcol = i;
  338.         }
  339.         if (destcol - outcol > 4 && i < COLS && (BC || BS)) {
  340.             if (TA)
  341.                 tputs(TA, 0, plodput);
  342.             else
  343.                 plodput('\t');
  344.             outcol = i;
  345.             while (outcol > destcol) {
  346.                 outcol--;
  347.                 if (BC)
  348.                     tputs(BC, 0, plodput);
  349.                 else
  350.                     plodput('\b');
  351.             }
  352.         }
  353.     }
  354.     while (outcol < destcol) {
  355.         /*
  356.          * move one char to the right.  We don't use ND space
  357.          * because it's better to just print the char we are
  358.          * moving over.
  359.          */
  360.         if (_win != NULL)
  361.             if (plodflg)    /* avoid a complex calculation */
  362.                 plodcnt--;
  363.             else {
  364.                 i = curscr->_y[outline][outcol];
  365.                 if ((i&_STANDOUT) == (curscr->_flags&_STANDOUT))
  366.                     _putchar(i, stdout);
  367.                 else
  368.                     goto nondes;
  369.             }
  370.         else
  371. nondes:
  372.              if (ND)
  373.             tputs(ND, 0, plodput);
  374.         else
  375.             plodput(' ');
  376.         outcol++;
  377.         if (plodcnt < 0)
  378.             goto out;
  379.     }
  380. out:
  381.     if (plodflg) {
  382.         outcol = soutcol;
  383.         outline = soutline;
  384.     }
  385.     return(plodcnt);
  386. }
  387.  
  388. /*
  389.  * Return the column number that results from being in column col and
  390.  * hitting a tab, where tabs are set every ts columns.  Work right for
  391.  * the case where col > COLS, even if ts does not divide COLS.
  392.  */
  393. int tabcol(col, ts)
  394. int col, ts;
  395. {
  396.     int offset;
  397.  
  398.     if (col >= COLS) {
  399.         offset = COLS * (col / COLS);
  400.         col -= offset;
  401.     }
  402.     else
  403.         offset = 0;
  404.     return col + ts - (col % ts) + offset;
  405. }
  406.